using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.ServiceModel.Description;
using System.Text;
using System.Web.Services.Description;
using System.Windows.Forms;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Microsoft.CSharp;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.Win32;
using OpenComposite.Base.Collections;
using OpenComposite.Base.Designer;
using OpenComposite.Forms;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.Designer.Workflow.Forms;
using OpenComposite.EII.Forms;
using OpenComposite.EII.Repository;
using OpenComposite.Workflow;
using WeifenLuo.WinFormsUI.Docking;
using System.Threading;

namespace OpenComposite.EII
{
	internal static class PropertyNames
	{
		public const string IsSimulation = "IsSimulation";
		public const string SimulateAllLogicalActivities = "SimulateAllLogicalActivities";
		public const string StartEventArgs = "StartEventArgs";
		public const string WorkflowInstanceId = "InstanceId";
		public const string ExternalDataEventArgs_InstanceId = "InstanceId";
		public const string IsDocumentFlowSimulation = "IsDocumentFlowSimulation";
	}

	public static class Helpers
	{

		#region Native  APIs

		#region Shell32
		/// <summary>
		/// Wraps necessary Shell32.dll structures and functions required to retrieve Icon Handles using SHGetFileInfo. Code
		/// courtesy of MSDN Cold Rooster Consulting case study.
		/// </summary>
		/// 
		// This code has been left largely untouched from that in the CRC example. The main changes have been moving
		// the icon reading code over to the IconReader type.
		public class Shell32
		{

			public const int MAX_PATH = 256;
			[StructLayout(LayoutKind.Sequential)]
			public struct SHITEMID
			{
				public ushort cb;
				[MarshalAs(UnmanagedType.LPArray)]
				public byte[] abID;
			}

			[StructLayout(LayoutKind.Sequential)]
			public struct ITEMIDLIST
			{
				public SHITEMID mkid;
			}

			[StructLayout(LayoutKind.Sequential)]
			public struct BROWSEINFO
			{
				public IntPtr hwndOwner;
				public IntPtr pidlRoot;
				public IntPtr pszDisplayName;
				[MarshalAs(UnmanagedType.LPTStr)]
				public string lpszTitle;
				public uint ulFlags;
				public IntPtr lpfn;
				public int lParam;
				public IntPtr iImage;
			}

			// Browsing for directory.
			public const uint BIF_RETURNONLYFSDIRS = 0x0001;
			public const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
			public const uint BIF_STATUSTEXT = 0x0004;
			public const uint BIF_RETURNFSANCESTORS = 0x0008;
			public const uint BIF_EDITBOX = 0x0010;
			public const uint BIF_VALIDATE = 0x0020;
			public const uint BIF_NEWDIALOGSTYLE = 0x0040;
			public const uint BIF_USENEWUI = ( BIF_NEWDIALOGSTYLE | BIF_EDITBOX );
			public const uint BIF_BROWSEINCLUDEURLS = 0x0080;
			public const uint BIF_BROWSEFORCOMPUTER = 0x1000;
			public const uint BIF_BROWSEFORPRINTER = 0x2000;
			public const uint BIF_BROWSEINCLUDEFILES = 0x4000;
			public const uint BIF_SHAREABLE = 0x8000;

			[StructLayout(LayoutKind.Sequential)]
			public struct SHFILEINFO
			{
				public const int NAMESIZE = 80;
				public IntPtr hIcon;
				public int iIcon;
				public uint dwAttributes;
				[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
				public string szDisplayName;
				[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)]
				public string szTypeName;
			};

			public const uint SHGFI_ICON = 0x000000100;     // get icon
			public const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
			public const uint SHGFI_TYPENAME = 0x000000400;     // get type name
			public const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
			public const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
			public const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
			public const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
			public const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
			public const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
			public const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
			public const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
			public const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
			public const uint SHGFI_OPENICON = 0x000000002;     // get open icon
			public const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
			public const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
			public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute
			public const uint SHGFI_ADDOVERLAYS = 0x000000020;     // apply the appropriate overlays
			public const uint SHGFI_OVERLAYINDEX = 0x000000040;     // Get the index of the overlay

			public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
			public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;

			[DllImport("Shell32.dll")]
			public static extern IntPtr SHGetFileInfo(
				string pszPath,
				uint dwFileAttributes,
				ref SHFILEINFO psfi,
				uint cbFileInfo,
				uint uFlags
				);
		}
		#endregion

		/// <summary>
		/// Wraps necessary functions imported from User32.dll. Code courtesy of MSDN Cold Rooster Consulting example.
		/// </summary>
		public class User32
		{
			/// <summary>
			/// Provides access to function required to delete handle. This method is used internally
			/// and is not required to be called separately.
			/// </summary>
			/// <param name="hIcon">Pointer to icon handle.</param>
			/// <returns>N/A</returns>
			[DllImport("User32.dll")]
			public static extern int DestroyIcon(IntPtr hIcon);
		}

		#endregion

		#region .Net DataTypes
		/// <summary>
		/// Gets the dot net type of data type string.
		/// </summary>
		/// <param name="datatype">The datatype.</param>
		/// <returns></returns>
		public static Type GetDotNetTypeOfDataTypeString(string datatype)
		{
			Type type = typeof(string);

			switch ( datatype.ToLower() ) {
				case "bool":
				case "boolean":
				case "system.boolean":
					type = typeof(bool);
					break;
				case "byte":
				case "unsignedbyte":
				case "system.byte":
					type = typeof(byte);
					break;
				case "sbyte":
				case "system.sbyte":
					type = typeof(sbyte);
					break;
				case "char":
				case "system.char":
					type = typeof(char);
					break;
				case "decimal":
				case "system.decimal":
					type = typeof(decimal);
					break;
				case "double":
				case "system.double":
					type = typeof(double);
					break;
				case "float":
				case "system.single":
					type = typeof(float);
					break;
				case "int":
				case "integer":
				case "system.int32":
					type = typeof(int);
					break;
				case "uint":
				case "unsignedint":
				case "system.uint32":
					type = typeof(uint);
					break;
				case "long":
				case "system.int64":
					type = typeof(long);
					break;
				case "ulong":
				case "unsignedlong":
				case "System.uint64":
					type = typeof(ulong);
					break;
				case "object":
				case "anyatomictype":
					type = typeof(object);
					break;
				case "short":
				case "system.int16":
					type = typeof(short);
					break;
				case "ushort":
				case "unsignedshort":
				case "system.uint16":
					type = typeof(ushort);
					break;
				case "string":
				case "system.string":
					type = typeof(string);
					break;
				case "time":
				case "datetime":
				case "date":
				case "system.datetime":
					type = typeof(DateTime);
					break;
				case "timespan":
				case "system.timespan":
				case "duration":
					type = typeof(TimeSpan);
					break;
				case "anyuri":
				case "uri":
				case "system.uri":
					type = typeof(Uri);
					break;
			}

			return type;
		}
		#endregion

		#region Create Compound Schemas
		/// <summary>
		/// Creates the compound canonical schema.
		/// </summary>
		/// <param name="schemas">The schemas.</param>
		/// <returns></returns>
		public static XmlSchema CreateCompoundCanonicalSchema(XmlSchema[] schemas)
		{
			if ( schemas.Length == 0 ) {
				return null;
			}

			XmlSchemaSet xset = new XmlSchemaSet();

			//init Compound Schema
			XmlSchema compSchema = new XmlSchema();
			compSchema.ElementFormDefault = XmlSchemaForm.Qualified;
			compSchema.AttributeFormDefault = XmlSchemaForm.Qualified;
			compSchema.TargetNamespace = schemas[0].TargetNamespace;
			compSchema.Namespaces.Add("tns", "http://www.theopencomposite.com/canonical_document");
			compSchema.Namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");

			//init sequence-Element for adding Elements to the Schema
			XmlSchemaElement element = new XmlSchemaElement();
			element.Name = "SubscribedDocuments";
			XmlSchemaComplexType complexType = new XmlSchemaComplexType();
			element.SchemaType = complexType;
			XmlSchemaSequence seq = new XmlSchemaSequence();
			complexType.Particle = seq;

			int counter = 0;
			foreach ( XmlSchema schema in schemas ) {
				foreach ( XmlQualifiedName qname in schema.Namespaces.ToArray() ) {
					if ( qname.Namespace == "http://www.w3.org/2001/XMLSchema" ||
						 qname.Namespace == "http://www.theopencomposite.com/canonical_document" )
						continue;

					compSchema.Namespaces.Add(string.Format("compSch{0}", counter),
						qname.Namespace);
					counter++;
				}
				xset.Add(schema);
			}
			xset.Compile();
			if ( !xset.IsCompiled ) {
				throw new Exception("Compiling Schemas failed in Helpers.CreateCompoundCanonicalSchema(..).");
			}
			for ( int i = 0; i < schemas.Length; i++ ) {
				foreach ( XmlSchemaObject schemaObj in schemas[i].Items ) {
					if ( schemaObj is XmlSchemaElement ) {
						bool exists = false;
						foreach ( XmlSchemaObject xmlObj in seq.Items ) {
							if ( xmlObj is XmlSchemaElement ) {
								if ( ( (XmlSchemaElement)xmlObj ).QualifiedName ==
									( (XmlSchemaElement)schemaObj ).QualifiedName ) {
									exists = true;
								}
							}
						}
						if ( exists == false ) {
							seq.Items.Add(schemaObj);
						}
					} else {
						if ( compSchema.Items.Contains(schemaObj) == false ) {
							compSchema.Items.Add(schemaObj);
						}
					}
				}
			}


			//add compound Element that contains the subscribed Elements
			if ( compSchema.Items.Contains(element) == false ) {
				compSchema.Items.Add(element);
			}

			xset = new XmlSchemaSet();
			xset.Add(compSchema);
			//xset.ValidationEventHandler += new ValidationEventHandler(this.validationEventHandler);
			xset.Compile();

			return compSchema;
		}
		/// <summary>
		/// Creates the compound schema.
		/// </summary>
		/// <param name="schemas">The schemas.</param>
		/// <param name="nameSpace">The name space.</param>
		/// <param name="wrappingElementName">Name of the wrapping element.</param>
		/// <returns></returns>
		public static XmlSchema CreateCompoundSchema(XmlSchema[] schemas,
			string nameSpace, string wrappingElementName)
		{
			if ( schemas.Length == 0 ) {
				return null;
			}

			XmlSchemaSet xset = new XmlSchemaSet();

			//init Compound Schema
			XmlSchema compSchema = new XmlSchema();
			compSchema.ElementFormDefault = XmlSchemaForm.Qualified;
			compSchema.AttributeFormDefault = XmlSchemaForm.Qualified;
			compSchema.TargetNamespace = schemas[0].TargetNamespace;
			compSchema.Namespaces.Add("tns", nameSpace);
			compSchema.Namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");

			//init sequence-Element for adding Elements to the Schema
			XmlSchemaElement element = new XmlSchemaElement();
			element.Name = wrappingElementName;
			XmlSchemaComplexType complexType = new XmlSchemaComplexType();
			element.SchemaType = complexType;
			XmlSchemaSequence seq = new XmlSchemaSequence();
			complexType.Particle = seq;

			int counter = 0;
			foreach ( XmlSchema schema in schemas ) {
				foreach ( XmlQualifiedName qname in schema.Namespaces.ToArray() ) {
					if ( qname.Namespace == "http://www.w3.org/2001/XMLSchema" ||
						 qname.Namespace == nameSpace )
						continue;

					compSchema.Namespaces.Add(string.Format("compSch{0}", counter),
						qname.Namespace);
					counter++;
				}
				xset.Add(schema);
			}
			xset.Compile();
			if ( !xset.IsCompiled ) {
				throw new Exception("Compiling Schemas failed in Helpers.CreateCompoundSchema(..).");
			}
			for ( int i = 0; i < schemas.Length; i++ ) {
				foreach ( XmlSchemaObject schemaObj in schemas[i].Items ) {
					if ( schemaObj is XmlSchemaElement ) {
						bool exists = false;
						foreach ( XmlSchemaObject xmlObj in seq.Items ) {
							if ( xmlObj is XmlSchemaElement ) {
								if ( ( (XmlSchemaElement)xmlObj ).QualifiedName ==
									( (XmlSchemaElement)schemaObj ).QualifiedName ) {
									exists = true;
								}
							}
						}
						if ( exists == false ) {
							seq.Items.Add(schemaObj);
						}
					} else {
						if ( compSchema.Items.Contains(schemaObj) == false ) {
							compSchema.Items.Add(schemaObj);
						}
					}
				}
			}


			//add compound Element that contains the subscribed Elements
			if ( compSchema.Items.Contains(element) == false ) {
				compSchema.Items.Add(element);
			}

			xset = new XmlSchemaSet();
			xset.Add(compSchema);
			//xset.ValidationEventHandler += new ValidationEventHandler(this.validationEventHandler);
			xset.Compile();

			return compSchema;
		}
		#endregion

		#region Set Activity Property
		/// <summary>
		/// Sets the activity property.
		/// </summary>
		/// <param name="activity">The activity.</param>
		/// <param name="propertyName">Name of the property.</param>
		/// <param name="value">The value.</param>
		internal static void SetActivityProperty(this Activity activity, string propertyName, object value)
		{
			PropertyDescriptor prop = TypeDescriptor.GetProperties(activity).Find(propertyName, false);
			if ( prop == null ) {
				throw new MissingMemberException(
					string.Format("The activity \"{0}\" does not contain the property \"{1}\".",
						activity.Name, propertyName));
			}
			prop.SetValue(activity, value);
		}
		#endregion

		#region Repository Item Type ImageList
		private static ImageList _imglistRepItemType = null;
		/// <summary>
		/// Gets the repository item type image list.
		/// </summary>
		/// <returns></returns>
		public static ImageList GetRepositoryItemTypeImageList()
		{
			if ( _imglistRepItemType != null ) return _imglistRepItemType; // EXIT

			_imglistRepItemType = new ImageList();
			_imglistRepItemType.ImageStream = Resources.imglistItemType;
			_imglistRepItemType.TransparentColor = System.Drawing.Color.Magenta;
			_imglistRepItemType.Images.SetKeyName(0, "folder_closed");
			_imglistRepItemType.Images.SetKeyName(1, "folder_open");
			_imglistRepItemType.Images.SetKeyName(2, "group");
			_imglistRepItemType.Images.SetKeyName(3, "computer");
			_imglistRepItemType.Images.SetKeyName(4, "field");
			_imglistRepItemType.Images.SetKeyName(5, "service");
			_imglistRepItemType.Images.SetKeyName(6, "class");
			_imglistRepItemType.Images.SetKeyName(7, "method");
			_imglistRepItemType.Images.SetKeyName(8, "brule");
			_imglistRepItemType.Images.SetKeyName(9, "bobject");
			_imglistRepItemType.Images.SetKeyName(10, "module");
			_imglistRepItemType.Images.SetKeyName(11, "policy");
			_imglistRepItemType.Images.SetKeyName(12, "diagram");
			_imglistRepItemType.Images.SetKeyName(13, "system");
			_imglistRepItemType.Images.SetKeyName(14, "bobj_folder_closed");
			_imglistRepItemType.Images.SetKeyName(15, "brule_folder_closed");
			_imglistRepItemType.Images.SetKeyName(16, "diagr_folder_closed");
			_imglistRepItemType.Images.SetKeyName(17, "module_folder_closed");
			_imglistRepItemType.Images.SetKeyName(18, "policy_folder_closed");
			_imglistRepItemType.Images.SetKeyName(19, "service_folder_closed");
			_imglistRepItemType.Images.SetKeyName(20, "vocab_folder_closed");
			_imglistRepItemType.Images.SetKeyName(21, "workflow");
			_imglistRepItemType.Images.SetKeyName(22, "webservice");
			_imglistRepItemType.Images.SetKeyName(23, "folder_closed_workflows");
			_imglistRepItemType.Images.SetKeyName(24, "folder_closed_webservices");
			_imglistRepItemType.Images.SetKeyName(25, "folder_closed_bprocess");
			_imglistRepItemType.Images.SetKeyName(26, "folder_closed_soa");
			_imglistRepItemType.Images.SetKeyName(27, "verb");
			_imglistRepItemType.Images.SetKeyName(28, "folder_closed_verb");
			_imglistRepItemType.Images.SetKeyName(29, "folder_closed_constant");
			_imglistRepItemType.Images.SetKeyName(30, "constant");
			_imglistRepItemType.Images.SetKeyName(31, "orchestration");
			_imglistRepItemType.Images.SetKeyName(32, "bprocess");
			_imglistRepItemType.Images.SetKeyName(33, "ha_component");
			_imglistRepItemType.Images.SetKeyName(34, "sql_component");
			_imglistRepItemType.Images.SetKeyName(35, "ui_component");
			_imglistRepItemType.Images.SetKeyName(36, "folder_closed_mashup");
			_imglistRepItemType.Images.SetKeyName(37, "folder_closed_user");
			_imglistRepItemType.Images.SetKeyName(38, "folder_closed_method");
			_imglistRepItemType.Images.SetKeyName(39, "mashup");
			_imglistRepItemType.Images.SetKeyName(40, "capability");
			_imglistRepItemType.Images.SetKeyName(41, "logical_method");
			_imglistRepItemType.Images.SetKeyName(42, "logical_method_group");
			_imglistRepItemType.Images.SetKeyName(43, "folder_closed_logmethod");
			_imglistRepItemType.Images.SetKeyName(44, "folder_closed_capability");
			_imglistRepItemType.Images.SetKeyName(45, "folder_closed_logmethgroup");
			_imglistRepItemType.Images.SetKeyName(46, "horizontalprocess");
			_imglistRepItemType.Images.SetKeyName(47, "png_org.png");
			_imglistRepItemType.Images.SetKeyName(48, "event");
			_imglistRepItemType.Images.SetKeyName(49, "documentation");
			_imglistRepItemType.Images.SetKeyName(50, "messagequeue");
			_imglistRepItemType.Images.SetKeyName(51, "folder_closed_mq");
			_imglistRepItemType.Images.SetKeyName(52, "kpi");

			return _imglistRepItemType;
		}
		#endregion

		#region Enum Value Description
		/// <summary>
		/// Gets the enum value description.
		/// </summary>
		/// <param name="element">The element.</param>
		/// <returns></returns>
		public static string GetEnumValueDescription(object element)
		{
			if ( element == null || !element.GetType().IsEnum ) {
				throw new ArgumentException("The argument \"element\" must be an enumeration value.", "element");
			}
			string s = null;
			object[] attrib = element.GetType().GetField(element.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
			if ( attrib != null && attrib.Length > 0 ) {
				s = ( (DescriptionAttribute)attrib[0] ).Description;
			}
			return s;
		}
		#endregion

		#region Debug Viewer
		/// <summary>
		/// Opens the debug viewer.
		/// </summary>
		/// <param name="item">The item.</param>
		[Conditional("DEBUG")]
		public static void OpenDebugViewer(this object item)
		{
			OpenDebugViewer(item, null);
		}
		/// <summary>
		/// Opens the debug viewer.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="owner">The owner.</param>
		[Conditional("DEBUG")]
		public static void OpenDebugViewer(this object item, IWin32Window owner)
		{
			if ( item != null ) {
				ItemDebugViewer frm = new ItemDebugViewer(item);
				if ( owner != null ) {
					frm.Show(owner);
				} else {
					frm.Show();
				}
			}
		}
		/// <summary>
		/// Opens the debug viewer dialog.
		/// </summary>
		/// <param name="item">The item.</param>
		[Conditional("DEBUG")]
		public static void OpenDebugViewerDialog(this object item)
		{
			OpenDebugViewerDialog(item, null);
		}
		/// <summary>
		/// Opens the debug viewer dialog.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="owner">The owner.</param>
		[Conditional("DEBUG")]
		public static void OpenDebugViewerDialog(this object item, IWin32Window owner)
		{
			if ( item != null ) {
				ItemDebugViewer frm = new ItemDebugViewer(item);
				if ( owner != null ) {
					frm.ShowDialog(owner);
				} else {
					frm.ShowDialog();
				}
			}
		}
		#endregion

		#region Open Diagram
		/// <summary>
		/// Opens the diagram.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <param name="type">The type.</param>
		/// <param name="serviceProvider">The service provider.</param>
		/// <returns></returns>
		public static bool OpenDiagram(int id, OpenComposite.EII.Repository.ItemType type, IServiceProvider serviceProvider)
		{
			IRepositoryItem item;
			if ( serviceProvider != null ) {
				RepositoryService repSvc = serviceProvider.GetService(typeof(RepositoryService)) as RepositoryService;
				item = repSvc.GetItem(type, id, false);
			} else {
				item = Global.Data.RepositoryService.GetItem(type, id, false);
			}
			return OpenDiagram(item, serviceProvider);
		}

		/// <summary>
		/// Opens the diagram.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="serviceProvider">The service provider.</param>
		/// <returns></returns>
		public static bool OpenDiagram(this IRepositoryItem item, IServiceProvider serviceProvider)
		{
			if ( ItemTypes.HasDiagram(item.RepositoryItemType) ) {
				IMainController mc = null;
				if ( serviceProvider != null ) {
					mc = serviceProvider.GetService(typeof(IMainController)) as IMainController;
				} else {
					mc = Global.Data.RepositoryService.GetService(typeof(IMainController)) as IMainController;
				}
				if ( mc != null ) {
					if ( item != null ) {
						RepositoryBusinessRule rule = item as RepositoryBusinessRule;
						if ( rule != null ) {
							BusinessPolicy policy = rule.GetPolicy();
							mc.OpenDiagram(policy);
						} else {
							mc.OpenDiagram(item);
						}
					}
				}
				return true;
			} else {
				return false;
			}
		}
		#endregion

		#region Show Details
		/// <summary>
		/// Shows the details.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <param name="type">The type.</param>
		/// <param name="serviceProvider">The service provider.</param>
		public static void ShowDetails(int id, OpenComposite.EII.Repository.ItemType type, IServiceProvider serviceProvider)
		{
			IRepositoryItem item;
			if ( serviceProvider != null ) {
				RepositoryService repSvc = serviceProvider.GetService(typeof(RepositoryService)) as RepositoryService;
				item = repSvc.GetItem(type, id, false);
			} else {
				item = Global.Data.RepositoryService.GetItem(type, id, false);
			}
			ShowDetails(item, serviceProvider);
		}

		/// <summary>
		/// Shows the details window for the repository item.
		/// </summary>
		/// <param name="item">The item.</param>
		public static void ShowDetails(this IRepositoryItem item)
		{
			ShowDetails(item, null);
		}
		/// <summary>
		/// Shows the details window for the repository item.
		/// </summary>
		/// <param name="item">The item to show.</param>
		/// <param name="serviceProvider">The service provider. Can be null.</param>
		public static void ShowDetails(this IRepositoryItem item, IServiceProvider serviceProvider)
		{
			IRepositoryExplorerView view = null;
			if ( serviceProvider != null ) {
				view = serviceProvider.GetService(typeof(IRepositoryExplorerView)) as IRepositoryExplorerView;
			} else {
				view = Global.Data.RepositoryService.GetService(typeof(IRepositoryExplorerView)) as IRepositoryExplorerView;
			}
			if ( view != null ) {
				view.SelectRepositoryItem(item);
			}
		}
		#endregion

		#region Temporary Files / Folder
		public const string OC_TEMP = "OpenComposite\\Temp";
		public static string TempPath
		{
			get { return Path.Combine(Path.GetTempPath(), OC_TEMP); }
		}

		/// <summary>
		/// Gets the new temp file path.
		/// </summary>
		/// <returns></returns>
		public static string GetNewTempFilePath()
		{
			return Path.Combine(TempPath, Path.GetRandomFileName());
		}
		/// <summary>
		/// Deletes the temp.
		/// </summary>
		[DebuggerStepThrough()]
		public static void DeleteTemp()
		{
			try { Directory.Delete(TempPath, true); } catch { }
		}
		#endregion

		#region Get Attributes of Type / Member
		/// <summary>
		/// Gets the first attribute of a specified type.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="type">The type.</param>
		/// <param name="inherit">if set to <c>true</c> [inherit].</param>
		/// <returns></returns>
		[DebuggerStepThrough()]
		public static T GetAttribute<T>(this Type type, bool inherit) where T : Attribute
		{
			object[] attributes = null;
			try {
				attributes = type.GetCustomAttributes(typeof(T), inherit);
			} catch { return null; }
			if ( attributes == null ) return null;
			foreach ( object attribute in attributes ) {
				if ( attribute is T ) return attribute as T;
			}
			return null;
		}
		/// <summary>
		/// Gets the attribute.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="member">The member.</param>
		/// <param name="inherit">if set to <c>true</c> [inherit].</param>
		/// <returns></returns>
		public static T GetAttribute<T>(this MemberInfo member, bool inherit) where T : Attribute
		{
			object[] attributes = null;
			try {
				attributes = member.GetCustomAttributes(typeof(T), inherit);
			} catch { return null; }
			if ( attributes == null ) return null;
			foreach ( object attribute in attributes ) {
				if ( attribute is T ) return attribute as T;
			}
			return null;
		}

		/// <summary>
		/// Gets the attributes.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="type">The type.</param>
		/// <param name="inherit">if set to <c>true</c> [inherit].</param>
		/// <returns></returns>
		public static List<T> GetAttributes<T>(this Type type, bool inherit) where T : Attribute
		{
			object[] attributes = type.GetCustomAttributes(typeof(T), inherit);
			List<T> listAttribs = new List<T>();
			foreach ( object attribute in attributes ) {
				if ( attribute is T ) listAttribs.Add(attribute as T);
			}
			return listAttribs;
		}
		/// <summary>
		/// Gets the attributes.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="member">The member.</param>
		/// <param name="inherit">if set to <c>true</c> [inherit].</param>
		/// <returns></returns>
		public static List<T> GetAttributes<T>(this MemberInfo member, bool inherit) where T : Attribute
		{
			object[] attributes = member.GetCustomAttributes(typeof(T), inherit);
			List<T> listAttribs = new List<T>();
			foreach ( object attribute in attributes ) {
				if ( attribute is T ) listAttribs.Add(attribute as T);
			}
			return listAttribs;
		}
		#endregion

		#region String Encryption / Compression

		/// <summary>
		/// Encrypts and compress a string.
		/// </summary>
		/// <param name="cleartext">The clear text.</param>
		/// <returns>The encrypted and compressed text.</returns>
		internal static string EncryptCompressString(string cleartext)
		{
			// Encryption Key / IV
			byte[] KEY =
				new byte[] { 0x69, 0x26, 0x5a, 0x33, 0xf, 0xae, 0xbb, 0xb3, 0xda, 0xf8,
						 0xf3, 0xa7, 0xd9, 0xcc, 0xb4, 0xea, 0x11, 0x10, 0xe, 0x43,
						 0x66, 0x19, 0x2a, 0x99, 0x13, 0xe, 0xea, 0xa3, 0x7d, 0x69,
						 0xee, 0x24 };
			byte[] IV =
				new byte[] { 0x57, 0xd0, 0x8d, 0xf8, 0x1d, 0x1f, 0xb4, 0xcd, 0x24, 0xf0,
						 0xfd, 0xbb, 0x18, 0x28, 0x29, 0xe1 };
			if ( string.IsNullOrEmpty(cleartext) ) return "";
			string encryptedtext = "";
			using ( MemoryStream ms = new MemoryStream() ) {
				try {
					RijndaelManaged myRijndael = new RijndaelManaged();
					//Get an encryptor.
					ICryptoTransform encryptor = myRijndael.CreateEncryptor(KEY, IV);
					//Encrypt the data.
					CryptoStream csEncrypt = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
					GZipStream zip = new GZipStream(csEncrypt, CompressionMode.Compress, true);
					StreamWriter sw = new StreamWriter(zip);
					sw.Write(cleartext);
					sw.Flush();
					zip.Flush();
					sw.Close();
					zip.Close();
					csEncrypt.FlushFinalBlock();
					csEncrypt.Close();
					byte[] buffer = ms.ToArray();
					encryptedtext = Convert.ToBase64String(buffer, 0, buffer.Length);
				} catch ( Exception ex ) {
					System.Diagnostics.Debug.WriteLine(ex.Message);
				}
			}
			KEY = null;
			IV = null;
			return encryptedtext;
		}
		/// <summary>
		/// Decrypts and decompress a string.
		/// </summary>
		/// <param name="encryptedText">The encrypted and compressed text.</param>
		/// <returns>The clear text</returns>
		internal static string DecryptDecompressString(string encryptedText)
		{
			// Encryption Key / IV
			byte[] KEY =
				new byte[] { 0x69, 0x26, 0x5a, 0x33, 0xf, 0xae, 0xbb, 0xb3, 0xda, 0xf8,
						 0xf3, 0xa7, 0xd9, 0xcc, 0xb4, 0xea, 0x11, 0x10, 0xe, 0x43,
						 0x66, 0x19, 0x2a, 0x99, 0x13, 0xe, 0xea, 0xa3, 0x7d, 0x69,
						 0xee, 0x24 };
			byte[] IV =
				new byte[] { 0x57, 0xd0, 0x8d, 0xf8, 0x1d, 0x1f, 0xb4, 0xcd, 0x24, 0xf0,
						 0xfd, 0xbb, 0x18, 0x28, 0x29, 0xe1 };
			if ( string.IsNullOrEmpty(encryptedText) ) return "";
			string cleartext = "";
			using ( MemoryStream ms = new MemoryStream(Convert.FromBase64String(encryptedText)) ) {
				RijndaelManaged myRijndael = new RijndaelManaged();
				//Get a decryptor.
				ICryptoTransform decryptor = myRijndael.CreateDecryptor(KEY, IV);
				//Decrypt the data.
				using ( CryptoStream csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Read) )
				using ( GZipStream zip = new GZipStream(csDecrypt, CompressionMode.Decompress) )
				using ( StreamReader sr = new StreamReader(zip) ) {
					cleartext = sr.ReadToEnd();
				}
			}
			KEY = null;
			IV = null;
			return cleartext;
		}

		/// <summary>
		/// Compresses a string.
		/// </summary>
		/// <param name="cleartext">The clear text.</param>
		/// <returns>The compressed text.</returns>
		internal static string CompressString(string cleartext)
		{
			if ( string.IsNullOrEmpty(cleartext) ) return "";
			string compressedtext = "";
			using ( MemoryStream ms = new MemoryStream() ) {
				try {
					GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
					StreamWriter sw = new StreamWriter(zip);
					sw.Write(cleartext);
					sw.Flush();
					zip.Flush();
					sw.Close();
					zip.Close();
					compressedtext = Convert.ToBase64String(ms.ToArray());
				} catch ( Exception ex ) {
					System.Diagnostics.Debug.WriteLine(ex.Message);
				}
			}
			return compressedtext;
		}
		/// <summary>
		/// Decompresses a string.
		/// </summary>
		/// <param name="compressedText">The compressed text.</param>
		/// <returns>The clear text.</returns>
		internal static string DecompressString(string compressedText)
		{
			if ( string.IsNullOrEmpty(compressedText) ) return "";
			string cleartext = "";
			using ( MemoryStream ms = new MemoryStream(Convert.FromBase64String(compressedText)) ) {
				using ( GZipStream zip = new GZipStream(ms, CompressionMode.Decompress) )
				using ( StreamReader sr = new StreamReader(zip) ) {
					cleartext = sr.ReadToEnd();
				}
			}
			return cleartext;
		}

		#endregion

		#region List Helpers
		/// <summary>
		/// Converts a enumerable list into anbinding list BindingListEx.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="list">The list.</param>
		/// <returns></returns>
		public static BindingListEx<T> ToBindingListEx<T>(this IEnumerable<T> list)
		{
			BindingListEx<T> newList = new BindingListEx<T>();
			newList.AddRange(list);
			return newList;
		}
		#endregion

		#region XML Serialization
		/// <summary>
		/// Gets the XML serialized object value of an XML string.
		/// </summary>
		/// <typeparam name="T">The type of the serialized object.</typeparam>
		/// <param name="columnname">The XML string.</param>
		/// <returns>The deserialized object of the XML string.</returns>
		internal static T XmlDeserializeObject<T>(string xmlstr) where T : class
		{
			return XmlDeserializeObject<T>(xmlstr, new Type[] { });
		}
		/// <summary>
		/// Gets the XML serialized object value of an XML string.
		/// </summary>
		/// <typeparam name="T">The type of the serialized object.</typeparam>
		/// <param name="columnname">The column name.</param>
		/// <param name="additionalTypes">The additional types.</param>
		/// <returns>The deserialized object of the XML string.</returns>
		internal static T XmlDeserializeObject<T>(string xmlstr, Type[] additionalTypes) where T : class
		{
			try {
				if ( string.IsNullOrEmpty(xmlstr) ) return null;
				XmlSerializer xs = null;
				if ( additionalTypes.Length == 0 ) xs = new XmlSerializer(typeof(T));
				else xs = new XmlSerializer(typeof(T), additionalTypes);
				using ( StringReader sr = new StringReader(xmlstr) ) {
					return xs.Deserialize(sr) as T;
				}
			} catch {
				return null;
			}
		}
		/// <summary>
		/// XML serialize an object.
		/// </summary>
		/// <param name="obj">The object to serialize.</param>
		/// <returns>The XML string of the object.</returns>
		internal static string XmlSerializeObject(object obj)
		{
			if ( obj == null ) {
				return null;
			} else {
				XmlSerializer xs = new XmlSerializer(obj.GetType());
				XmlWriterSettings settings = new XmlWriterSettings();
				settings.Indent = false;
				settings.OmitXmlDeclaration = true;
				using ( StringWriter sw = new StringWriter() )
				using ( XmlWriter xw = XmlWriter.Create(sw, settings) ) {
					xs.Serialize(xw, obj);
					return sw.ToString();
				}
			}
		}
		#endregion

		#region XML Helpers
		/// <summary>
		/// Converts an XmlSchema into a displayable string.
		/// </summary>
		/// <param name="schema">The schema.</param>
		/// <returns></returns>
		public static string ToDisplayableString(this XmlSchema schema)
		{
			if ( schema == null ) return null;
			XmlDocument xd = new XmlDocument();
			using ( StringWriter sw = new StringWriter() ) {
				schema.Write(sw);
				xd.LoadXml(sw.ToString());
			}
			return xd.OuterXml;
		}
		#endregion

		#region Repository Item Helpers
		/// <summary>
		/// Determines whether [is valid char for name] [the specified c].
		/// </summary>
		/// <param name="c">The c.</param>
		/// <returns>
		/// 	<c>true</c> if [is valid char for name] [the specified c]; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsValidCharForName(char c)
		{
			if ( c < (char)32 ) return true;
			return _validIdentifierCharacters.Contains(c);
		}

		private static Forms.FormBObjectViewer _frmBOViewer = null;
		/// <summary>
		/// Shows the business object tree.
		/// </summary>
		/// <param name="bobject">The bobject.</param>
		public static void ShowBusinessObjectTree(this BusinessObject bobject)
		{
			ShowBusinessObjectTree(bobject, null);
		}
		/// <summary>
		/// Shows the business object tree.
		/// </summary>
		/// <param name="bobject">The bobject.</param>
		/// <param name="caption">The caption.</param>
		public static void ShowBusinessObjectTree(this BusinessObject bobject, string caption)
		{
			if ( _frmBOViewer == null ) _frmBOViewer = new FormBObjectViewer();
			_frmBOViewer.BusinessObject = bobject;
			_frmBOViewer.StartPosition = FormStartPosition.CenterScreen;
			if ( !string.IsNullOrEmpty(caption) ) {
				_frmBOViewer.Text = caption;
			}
			_frmBOViewer.ShowDialog();
		}

		private static FormCodeViewer _frmCodeEditor = null;
		/// <summary>
		/// Shows the business object code.
		/// </summary>
		/// <param name="bobject">The bobject.</param>
		public static void ShowBusinessObjectCode(this BusinessObject bobject)
		{
			if ( _frmCodeEditor == null ) _frmCodeEditor = new FormCodeViewer();
			_frmCodeEditor.Code = bobject.GenerateCSharpCode();
			_frmCodeEditor.StartPosition = FormStartPosition.CenterScreen;
			_frmCodeEditor.ShowDialog();
		}

		/// <summary>
		/// Formats an XML string.
		/// </summary>
		/// <param name="xmlstr">The XMLSTR.</param>
		/// <returns></returns>
		public static string FormatXmlString(string xmlstr)
		{
			XmlDocument xd = new XmlDocument();
			xd.LoadXml(xmlstr);
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.Indent = true;
			settings.IndentChars = "\t";
			using ( StringWriter sw = new StringWriter() )
			using ( XmlWriter xw = XmlWriter.Create(sw, settings) ) {
				xd.WriteTo(xw);
				xw.Flush();
				return sw.ToString();
			}
		}

		#endregion

		#region Workflow Helpers
		/// <summary>
		/// Gets the root activity.
		/// </summary>
		/// <param name="activity">The activity.</param>
		/// <returns></returns>
		internal static Activity GetRootActivity(this Activity activity)
		{
			if ( activity == null )
				throw new ArgumentNullException("activity");

			while ( activity.Parent != null )
				activity = activity.Parent;

			return activity;
		}
		/// <summary>
		/// Gets the root activity.
		/// </summary>
		/// <param name="fileName">Name of the file.</param>
		/// <returns></returns>
		internal static Activity GetRootActivity(string fileName)
		{
			XmlReader reader = new XmlTextReader(fileName);
			Activity rootActivity = null;
			try {
				WorkflowMarkupSerializer xomlSerializer = new WorkflowMarkupSerializer();
				rootActivity = xomlSerializer.Deserialize(reader) as Activity;
			} finally {
				reader.Close();
			}
			return rootActivity;

		}
		/// <summary>
		/// Gets the root activity.
		/// </summary>
		/// <param name="workflow">The workflow.</param>
		/// <returns></returns>
		internal static Activity GetRootActivity(this Repository.Workflow workflow)
		{
			if ( string.IsNullOrEmpty(workflow.XOML) )
				return null;

			Activity rootActivity = null;
			using ( StringReader sr = new StringReader(workflow.XOML) )
			using ( XmlReader reader = new XmlTextReader(sr) ) {
				WorkflowMarkupSerializer xomlSerializer = new WorkflowMarkupSerializer();
				rootActivity = xomlSerializer.Deserialize(reader) as Activity;
			}
			return rootActivity;

		}

		/// <summary>
		/// Gets the data source class.
		/// </summary>
		/// <param name="activity">The activity.</param>
		/// <param name="serviceProvider">The service provider.</param>
		/// <returns></returns>
		internal static Type GetDataSourceClass(this Activity activity, IServiceProvider serviceProvider)
		{
			if ( activity == null )
				throw new ArgumentNullException("activity");
			if ( serviceProvider == null )
				throw new ArgumentNullException("serviceProvider");

			Type activityType = null;
			string className = null;
			if ( activity == GetRootActivity(activity) )
				className = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;

			if ( !String.IsNullOrEmpty(className) ) {
				ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider));
				if ( typeProvider == null )
					throw new InvalidOperationException(typeof(ITypeProvider).Name);

				activityType = typeProvider.GetType(className);
			} else {
				return activity.GetType();
			}

			return activityType;
		}

		/// <summary>
		/// Generates the code from xoml document.
		/// </summary>
		/// <param name="rootActivity">The root activity.</param>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="nameSpace">The name space.</param>
		/// <param name="typeName">Name of the type.</param>
		/// <returns></returns>
		internal static CodeNamespace GenerateCodeFromXomlDocument(
			Activity rootActivity,
			IServiceProvider serviceProvider,
			ref string nameSpace,
			ref string typeName)
		{
			if ( rootActivity == null ) return null;

			CodeNamespaceCollection codeNamespaces = new CodeNamespaceCollection();
			CSharpCodeProvider codeDomProvider = new CSharpCodeProvider();

			// generate activity class
			string activityFullClassName = rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string;
			CodeTypeDeclaration activityTypeDeclaration = null;
			CodeNamespace activityCodeNamespace = null;

			if ( codeDomProvider != null && !string.IsNullOrEmpty(activityFullClassName) ) {
				// get class and namespace names
				string activityNamespaceName, activityClassName;
				Helpers.GetNamespaceAndClassName(activityFullClassName, out activityNamespaceName, out activityClassName);
				nameSpace = activityNamespaceName;
				typeName = activityClassName;

				if ( codeDomProvider.IsValidIdentifier(activityClassName) ) {
					DesignerSerializationManager designerSerializationManager = new DesignerSerializationManager(serviceProvider);
					using ( designerSerializationManager.CreateSession() ) {
						ActivityCodeDomSerializationManager codeDomSerializationManager = new ActivityCodeDomSerializationManager(designerSerializationManager);
						TypeCodeDomSerializer typeCodeDomSerializer = codeDomSerializationManager.GetSerializer(rootActivity.GetType(), typeof(TypeCodeDomSerializer)) as TypeCodeDomSerializer;

						// get all activities
						bool generateCode = true;

						ArrayList allActivities = new ArrayList();
						allActivities.Add(rootActivity);
						if ( rootActivity is CompositeActivity ) {
							foreach ( Activity activity in Helpers.GetNestedActivities((CompositeActivity)rootActivity) ) {
								if ( Helpers.IsActivityLocked(activity) )
									continue;
								if ( codeDomProvider.IsValidIdentifier(codeDomSerializationManager.GetName(activity)) ) {
									allActivities.Insert(0, activity);
								} else {
									throw new Exception(
										string.Format("The activity name \"{0}\" is not a valid identifier.",
											codeDomSerializationManager.GetName(activity)));
									//generateCode = false;
									//break;
								}
							}
						}

						if ( generateCode ) {
							DummySite dummySite = new DummySite();
							foreach ( Activity nestedActivity in allActivities )
								( (IComponent)nestedActivity ).Site = dummySite;
							( (IComponent)rootActivity ).Site = dummySite;

							// create activity partial class
							activityTypeDeclaration = typeCodeDomSerializer.Serialize(codeDomSerializationManager, rootActivity, allActivities);
							activityTypeDeclaration.IsPartial = true;

							// create a new namespace and add activity class into that
							activityCodeNamespace = new CodeNamespace(activityNamespaceName);
							activityCodeNamespace.Types.Add(activityTypeDeclaration);
						}
					}
				}
			}

			if ( activityTypeDeclaration != null ) {
				Queue activitiesQueue = new Queue(new object[] { rootActivity });
				while ( activitiesQueue.Count > 0 ) {
					Activity activity = (Activity)activitiesQueue.Dequeue();
					if ( Helpers.IsActivityLocked(activity) )
						continue;

					Queue childActivities = new Queue(new object[] { activity });
					while ( childActivities.Count > 0 ) {
						Activity childActivity = (Activity)childActivities.Dequeue();
						if ( childActivity is CompositeActivity ) {
							foreach ( Activity nestedChildActivity in ( (CompositeActivity)childActivity ).Activities ) {
								childActivities.Enqueue(nestedChildActivity);
							}
						}

						CodeTypeMemberCollection codeSegments = childActivity.GetValue(WorkflowMarkupSerializer.XCodeProperty) as CodeTypeMemberCollection;
						if ( codeSegments != null ) {
							foreach ( CodeSnippetTypeMember codeSegmentMember in codeSegments )
								activityTypeDeclaration.Members.Add(codeSegmentMember);
						}
					}
				}


				activityTypeDeclaration.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1));
				CodeConstructor constructor = null;
				CodeMemberMethod method = null;
				foreach ( CodeTypeMember typeMember in activityTypeDeclaration.Members ) {
					if ( constructor == null && typeMember is CodeConstructor )
						constructor = typeMember as CodeConstructor;

					if ( method == null && typeMember is CodeMemberMethod && typeMember.Name.Equals("InitializeComponent", StringComparison.Ordinal) )
						method = typeMember as CodeMemberMethod;

					if ( constructor != null && method != null )
						break;
				}

				if ( constructor != null )
					constructor.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1));

				method.LinePragma = new CodeLinePragma((string)rootActivity.GetValue(ActivityCodeDomSerializer.MarkupFileNameProperty), Math.Max((int)rootActivity.GetValue(ActivityMarkupSerializer.StartLineProperty), 1));
			}
			return activityCodeNamespace;
		}

		/// <summary>
		/// Gets the name of the namespace and class.
		/// </summary>
		/// <param name="fullQualifiedName">Full name of the qualified.</param>
		/// <param name="namespaceName">Name of the namespace.</param>
		/// <param name="className">Name of the class.</param>
		internal static void GetNamespaceAndClassName(string fullQualifiedName, out string namespaceName, out string className)
		{
			namespaceName = String.Empty;
			className = String.Empty;

			if ( fullQualifiedName == null )
				return;

			int indexOfDot = fullQualifiedName.LastIndexOf('.');
			if ( indexOfDot != -1 ) {
				namespaceName = fullQualifiedName.Substring(0, indexOfDot);
				className = fullQualifiedName.Substring(indexOfDot + 1);
			} else {
				className = fullQualifiedName;
			}
		}

		/// <summary>
		/// Gets the nested activities.
		/// </summary>
		/// <param name="compositeActivity">The composite activity.</param>
		/// <returns></returns>
		internal static List<Activity> GetNestedActivities(this CompositeActivity compositeActivity)
		{
			List<Activity> activities = new List<Activity>();
			if ( compositeActivity == null ) return activities;
			foreach ( Activity act in compositeActivity.Activities ) {
				activities.Add(act);
				if ( act is CompositeActivity ) {
					activities.AddRange(Helpers.GetNestedActivities((CompositeActivity)act));
				}
			}
			return activities;
		}

		/// <summary>
		/// Adds the object graph to designer host.
		/// </summary>
		/// <param name="designerHost">The designer host.</param>
		/// <param name="activity">The activity.</param>
		internal static void AddObjectGraphToDesignerHost(IDesignerHost designerHost, Activity activity)
		{
			if ( designerHost == null )
				throw new ArgumentNullException("designerHost");
			if ( activity == null )
				throw new ArgumentNullException("activity");

			string rootSiteName = activity.QualifiedName;
			designerHost.Container.Add(activity, activity.QualifiedName);

			if ( activity is CompositeActivity ) {
				foreach ( Activity activity2 in GetNestedActivities(activity as CompositeActivity) )
					designerHost.Container.Add(activity2, activity2.QualifiedName);
			}
		}

		/// <summary>
		/// Determines whether [is activity locked] [the specified activity].
		/// </summary>
		/// <param name="activity">The activity.</param>
		/// <returns>
		/// 	<c>true</c> if [is activity locked] [the specified activity]; otherwise, <c>false</c>.
		/// </returns>
		internal static bool IsActivityLocked(this Activity activity)
		{
			if ( activity == null )
				throw new ArgumentNullException("activity");

			CompositeActivity parent = activity.Parent;
			while ( parent != null ) {
				// If root, not locked
				if ( parent.Parent == null )
					return false;

				// Any custom activity found, then locked
				if ( IsCustomActivity(parent) )
					return true;

				parent = parent.Parent;
			}

			return false;
		}

		/// <summary>
		/// Determines whether [is custom activity] [the specified composite activity].
		/// </summary>
		/// <param name="compositeActivity">The composite activity.</param>
		/// <returns>
		/// 	<c>true</c> if [is custom activity] [the specified composite activity]; otherwise, <c>false</c>.
		/// </returns>
		internal static bool IsCustomActivity(this CompositeActivity compositeActivity)
		{
			if ( compositeActivity == null )
				throw new ArgumentNullException("compositeActivity");

			Guid CustomActivity = new Guid("298CF3E0-E9E0-4d41-A11B-506E9132EB27");
			Guid CustomActivityDefaultName = new Guid("8bcd6c40-7bf6-4e60-8eea-bbf40bed92da");

			if ( compositeActivity.UserData.Contains(new Guid("298CF3E0-E9E0-4d41-A11B-506E9132EB27")) ) {
				return (bool)( compositeActivity.UserData[CustomActivity] );
			} else {
				try {
					CompositeActivity activity = Activator.CreateInstance(compositeActivity.GetType()) as CompositeActivity;
					if ( activity != null && activity.Activities.Count > 0 ) {
						compositeActivity.UserData[CustomActivityDefaultName] = activity.Name;
						compositeActivity.UserData[CustomActivity] = true;
						return true;
					}
				} catch {
				}
			}

			compositeActivity.UserData[CustomActivity] = false;
			return false;
		}

		internal static T GetActivityByLogicalActivityID<T>(this CompositeActivity compositeActivity, int logactid) where T : Activity
		{
			return GetActivityByLogicalActivityID(GetNestedActivities(compositeActivity), logactid) as T;
		}

		internal static T GetActivityByLogicalActivityID<T>(this IEnumerable<Activity> activities, int logactid) where T : Activity
		{
			return GetActivityByLogicalActivityID(activities, logactid) as T;
		}

		internal static Activity GetActivityByLogicalActivityID(this CompositeActivity compositeActivity, int logactid)
		{
			return GetActivityByLogicalActivityID(GetNestedActivities(compositeActivity), logactid);
		}

		internal static Activity GetActivityByLogicalActivityID(this IEnumerable<Activity> activities, int logactid)
		{
			foreach ( Activity item in activities ) {
				ILogicalActivity la = item as ILogicalActivity;
				if ( la != null && la.LogicalActivityId == logactid ) {
					return item;
				}
			}
			return null;
		}

		internal static void ConfigNotification(this Repository.Workflow workflow, Repository.LogicalActivity logact)
		{
			NotificationActivity activity = null;
			IDesignerHost host = workflow.GetService(typeof(IDesignerHost)) as IDesignerHost;
			if ( host != null && host.RootComponent is CompositeActivity ) {
				activity = Helpers.GetActivityByLogicalActivityID(
					(CompositeActivity)host.RootComponent, logact.ID)
					as NotificationActivity;
			} else {
				activity = Helpers.GetActivityByLogicalActivityID(
					Helpers.GetRootActivity(workflow) as CompositeActivity, logact.ID)
					 as NotificationActivity;
			}
			if ( activity == null ) return;
			using ( UIConfigXML form = new UIConfigXML(activity.Notification, workflow, activity.LogicalActivityId) ) {
				form.SmtpData = new OpenComposite.Mapper.ConfigSMTPInputData();
				form.SmtpData.SMTPUser = activity.NotificationUserName;
				form.SmtpData.SMTPSender = activity.NotificationSender;
				form.SmtpData.SMTPServer = activity.NotificationHost;
				form.SmtpData.SMTPPassword = activity.NotificationPassword;
				form.ActivityName = activity.Text;

				if ( form.ShowDialog() == DialogResult.OK ) {
					TypeDescriptor.GetProperties(activity)["Notification"].SetValue(activity, form.Notification);
					TypeDescriptor.GetProperties(activity)["NotificationHost"].SetValue(activity, form.SmtpData.SMTPServer);
					TypeDescriptor.GetProperties(activity)["NotificationUserName"].SetValue(activity, form.SmtpData.SMTPUser);
					TypeDescriptor.GetProperties(activity)["NotificationUserName"].SetValue(activity, form.SmtpData.SMTPUser);
					TypeDescriptor.GetProperties(activity)["NotificationPassword"].SetValue(activity, form.SmtpData.SMTPPassword);

				}
			}
		}
		internal static bool IsNotificationConfigurated(this Repository.Workflow workflow, Repository.LogicalActivity logact)
		{
			NotificationActivity activity = null;
			IDesignerHost host = workflow.GetService(typeof(IDesignerHost)) as IDesignerHost;
			if ( host != null && host.RootComponent is CompositeActivity ) {
				activity = Helpers.GetActivityByLogicalActivityID(
					(CompositeActivity)host.RootComponent, logact.ID)
					as NotificationActivity;
			} else {
				activity = Helpers.GetActivityByLogicalActivityID(
					Helpers.GetRootActivity(workflow) as CompositeActivity, logact.ID)
					 as NotificationActivity;
			}
			if ( activity == null ) return false;
			bool bMissing = activity.Notification == null ||
							string.IsNullOrEmpty(activity.Notification.Message) ||
							string.IsNullOrEmpty(activity.Notification.Recipient) ||
							string.IsNullOrEmpty(activity.Notification.Subject) ||
							string.IsNullOrEmpty(activity.NotificationHost) ||
							string.IsNullOrEmpty(activity.NotificationSender);

			return !bMissing;
		}

		internal static T GetMember<T>(CodeCompileUnit codeUnit, string className, string memberName)
			where T : CodeTypeMember
		{
			foreach ( CodeNamespace codeNS in codeUnit.Namespaces ) {
				if ( !className.StartsWith(codeNS.Name) ) continue;
				foreach ( CodeTypeDeclaration codeType in codeNS.Types ) {
					if ( !className.EndsWith(codeType.Name) ) continue;
					foreach ( CodeTypeMember current in codeType.Members ) {
						T member = current as T;
						if ( member != null && member.Name == memberName ) {
							return member;
						}
					}
				}
			}
			return null;
		}

		private class DummySite : ISite
		{
			public IComponent Component { get { return null; } }
			public IContainer Container { get { return null; } }
			public bool DesignMode { get { return true; } }
			public string Name { get { return string.Empty; } set { } }
			public object GetService(Type type) { return null; }
		}
		#endregion

		#region IdentifierHelpers

		private static List<char> _validIdentifierCharacters =
			new List<char>(new char[]{
				'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
				'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
				'1','2','3','4','5','6','7','8','9','0','_'
			});

		/// <summary>
		/// Provides a mechanism to test that an identifier is unique within an System.Workflow.ComponentModel.Activity.
		/// </summary>
		/// <param name="identifierSerivce">The identifier serivce.</param>
		/// <param name="activity">The System.Workflow.ComponentModel.Activity against which to test the identifier.</param>
		/// <param name="identifier">The identifier.</param>
		/// <returns><c>true</c> if characters is valid; otherwise <c>false</c>.</returns>
		internal static bool ValidateIdentifier(IIdentifierCreationService identifierSerivce, Activity activity, string identifier)
		{
			return ValidateIdentifier(identifierSerivce, activity, ref identifier, false);
		}

		/// <summary>
		/// Provides a mechanism to test that an identifier is unique within an System.Workflow.ComponentModel.Activity.
		/// </summary>
		/// <param name="identifierSerivce">The identifier serivce.</param>
		/// <param name="activity">The System.Workflow.ComponentModel.Activity against which to test the identifier.</param>
		/// <param name="identifier">The identifier.</param>
		/// <param name="autoCorrect">if set to <c>true</c> automatically correct invalid identifiers.</param>
		/// <returns><c>true</c> if characters is valid; otherwise <c>false</c>.</returns>
		internal static bool ValidateIdentifier(IIdentifierCreationService identifierSerivce, Activity activity, ref string identifier, bool autoCorrect)
		{
			if ( identifierSerivce != null ) {
				try {
					identifierSerivce.ValidateIdentifier(activity, identifier);
				} catch {
					if ( IsValidIdentifier(identifier) ) {
						// no invalid characters found.
						// the name is most likely given to another activity.
						MessageBox.Show(
							string.Format("Invalid identifier '{0}'!", identifier),
							"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
					} else {
						if ( autoCorrect ) {
							identifier = CorrectInvalidIdentifier(identifier);
							return true;
						} else {
							MessageBox.Show(
								string.Format("Identifier '{0}' contains one or more invalid characters!", identifier),
								"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
						}
					}
					return false;
				}
			}
			return true;
		}

		internal static bool IsValidIdentifier(string identifier)
		{
			foreach ( char c in identifier ) {
				if ( !_validIdentifierCharacters.Contains(c) ) return false;
			}
			return true;
		}

		internal static string CorrectInvalidIdentifier(string identifier)
		{
			foreach ( char c in identifier ) {
				if ( !_validIdentifierCharacters.Contains(c) ) {
					identifier = identifier.Replace(c, '_');
				}
			}
			return identifier;
		}
		#endregion

		#region Dock Panel Helpers

		public static void CloseAllWindows(this DockPanel panel)
		{
			CloseAllWindows(panel, null);
		}

		public static void CloseAllWindows(this DockPanel panel, IDockContent butThis)
		{
			if ( panel == null || panel.Documents == null ) return;
			List<IDockContent> documents = new List<IDockContent>(panel.Documents);
			for ( int i = documents.Count - 1; i >= 0; i-- ) {
				IDockContent doc = documents[i];
				if ( doc is formDomainEditor ) continue;
				if ( doc.DockHandler == null ) continue;
				if ( doc == butThis ) continue;
				doc.DockHandler.Close();
			}
		}

		#endregion

		#region Convert Helpers

		/// <summary>
		/// Helper Enumeration for default Response Time Units (KPIs)
		/// </summary>
		public enum ResponseTimeUnit
		{
			/// <summary>
			/// Milliseconds
			/// </summary>
			ms = 0,
			/// <summary>
			/// Seconds
			/// </summary>
			s,
			/// <summary>
			/// Minutes
			/// </summary>
			min,
			/// <summary>
			/// Hours
			/// </summary>
			h,
			/// <summary>
			/// Days
			/// </summary>
			d
		}
		public static decimal ConvertUnit(string value, KpiUnit sourceUnit, KpiUnit targetUnit)
		{
			decimal number;
			decimal.TryParse(value.Replace(',', '.'), NumberStyles.Float,
				CultureInfo.InvariantCulture.NumberFormat, out number);
			return ConvertUnit(number, sourceUnit, targetUnit);
		}
		public static decimal ConvertUnit(decimal value, KpiUnit sourceUnit, KpiUnit targetUnit)
		{
			decimal result = value;
			if ( sourceUnit == null || targetUnit == null ) return result;
			if ( sourceUnit.IsBaseUnit ) {
				result = calculateConversion(value, getOppositeSign(targetUnit.OperationSign), targetUnit.OperationValue);
			} else if ( targetUnit.IsBaseUnit ) {
				result = calculateConversion(value, sourceUnit.OperationSign, sourceUnit.OperationValue);
			} else {
				result = calculateConversion(
					calculateConversion(value, getOppositeSign(sourceUnit.OperationSign),
						sourceUnit.OperationValue),
					targetUnit.OperationSign, targetUnit.OperationValue);
			}

			return result;
		}

		private static decimal calculateConversion(decimal value, string operationSign, decimal operationValue)
		{
			decimal result = value;
			switch ( operationSign ) {
				case "+":
					result = value + operationValue;
					break;
				case "-":
					result = value - operationValue;
					break;
				case "*":
					result = value * operationValue;
					break;
				case "/":
					result = value / operationValue;
					break;
				default:
					break;
			}
			return result;
		}

		private static string getOppositeSign(string sign)
		{
			switch ( sign ) {
				case "+":
					return "-";
				case "-":
					return "+";
				case "*":
					return "/";
				case "/":
					return "*";
				default:
					return sign;
			}
		}

		///// <summary>
		///// Converts the given value from or to percent. Possible units are empty <see cref="T:System.String"/> or null and the % character
		///// </summary>
		///// <param name="value">The value to convert.</param>
		///// <param name="sourceUnit">The source unit.</param>
		///// <param name="targetUnit">The target unit.</param>
		///// <returns></returns>
		//public static decimal ConvertPercent(string value, string sourceUnit, string targetUnit)
		//{
		//    decimal number;
		//    decimal.TryParse(value.Replace(',', '.'), NumberStyles.Float,
		//        CultureInfo.InvariantCulture.NumberFormat, out number);
		//    return ConvertPercent(number, sourceUnit, targetUnit);
		//}
		///// <summary>
		///// Converts the given value from or to percent. Possible units are empty <see cref="T:System.String"/> or null and the % character
		///// </summary>
		///// <param name="value">The value to convert.</param>
		///// <param name="sourceUnit">The source unit.</param>
		///// <param name="targetUnit">The target unit.</param>
		///// <returns></returns>
		//public static decimal ConvertPercent(decimal value, string sourceUnit, string targetUnit)
		//{
		//    if ( sourceUnit == targetUnit ) return value;
		//    decimal result = value;
		//    if ( targetUnit == "%" ) {
		//        if ( string.IsNullOrEmpty(sourceUnit) ) {
		//            result = value * 100;
		//        }
		//    } else if ( string.IsNullOrEmpty(targetUnit) ) {
		//        if ( sourceUnit == "%" ) {
		//            result = value / 100;
		//        }
		//    }
		//    return result;
		//}
		///// <summary>
		///// Converts the <see cref="T:System.Decimal"/> from a specified format to the target format.
		///// </summary>
		///// <param name="value">The value.</param>
		///// <param name="sourceFormat">The source format.</param>
		///// <param name="targetFormat">The target format.</param>
		///// <returns></returns>
		//public static decimal ConvertTime(decimal value, ResponseTimeUnit sourceFormat, ResponseTimeUnit targetFormat)
		//{
		//    return ConvertTime(value, 
		//        Enum.GetName(typeof(ResponseTimeUnit), sourceFormat), 
		//        Enum.GetName(typeof(ResponseTimeUnit), targetFormat));
		//}
		///// <summary>
		///// Converts the <see cref="T:System.String"/> as a <see cref="T:System.Decimal"/> from a specified format to the target format.
		///// </summary>
		///// <param name="value">The value.</param>
		///// <param name="sourceFormat">The source format.</param>
		///// <param name="targetFormat">The target format.</param>
		///// <returns></returns>
		//public static decimal ConvertTime(string value, ResponseTimeUnit sourceFormat, ResponseTimeUnit targetFormat)
		//{
		//    return ConvertTime(value,
		//        Enum.GetName(typeof(ResponseTimeUnit), sourceFormat),
		//        Enum.GetName(typeof(ResponseTimeUnit), targetFormat));
		//}
		///// <summary>
		///// Converts the <see cref="T:System.String"/> as a <see cref="T:System.Decimal"/> from a specified format to the target format.
		///// </summary>
		///// <param name="value">The value.</param>
		///// <param name="sourceFormat">The source format.</param>
		///// <param name="targetFormat">The target format.</param>
		///// <returns></returns>
		//public static decimal ConvertTime(string value, string sourceFormat, string targetFormat)
		//{
		//    decimal number;
		//    decimal.TryParse(value.Replace(',', '.'), NumberStyles.Float,
		//        CultureInfo.InvariantCulture.NumberFormat, out number);
		//    return ConvertTime(number, sourceFormat, targetFormat);
		//}

		///// <summary>
		///// Converts the <see cref="T:System.Decimal"/> from a specified format to the target format.
		///// </summary>
		///// <param name="value">The value.</param>
		///// <param name="sourceFormat">The source format.</param>
		///// <param name="targetFormat">The target format.</param>
		///// <returns></returns>
		//public static decimal ConvertTime(decimal value, string sourceFormat, string targetFormat)
		//{
		//    decimal result = value;
		//    if ( sourceFormat == targetFormat ) return result;
		//    if ( targetFormat == "ms" ) {
		//        if ( sourceFormat == "s" ) {
		//            result = value * 1000;
		//        } else if ( sourceFormat == "min" ) {
		//            result = value * 60000;
		//        } else if ( sourceFormat == "h" ) {
		//            result = value * 3600000;
		//        } else if ( sourceFormat == "d" ) {
		//            result = value * 86400000;
		//        }
		//    } else if ( targetFormat == "s" ) {
		//        if ( sourceFormat == "ms" ) {
		//            result = value / 1000;
		//        } else if ( sourceFormat == "min" ) {
		//            result = value * 60;
		//        } else if ( sourceFormat == "h" ) {
		//            result = value * 3600;
		//        } else if ( sourceFormat == "d" ) {
		//            result = value * 86400;
		//        }
		//    } else if ( targetFormat == "min" ) {
		//        if ( sourceFormat == "ms" ) {
		//            result = value / 60000;
		//        } else if ( sourceFormat == "s" ) {
		//            result = value / 60;
		//        } else if ( sourceFormat == "h" ) {
		//            result = value * 60;
		//        } else if ( sourceFormat == "d" ) {
		//            result = value * 1440;
		//        }
		//    } else if ( targetFormat == "h" ) {
		//        if ( sourceFormat == "ms" ) {
		//            result = value / 3600000;
		//        } else if ( sourceFormat == "s" ) {
		//            result = value / 3600;
		//        } else if ( sourceFormat == "min" ) {
		//            result = value / 60;
		//        } else if ( sourceFormat == "d" ) {
		//            result = value * 24;
		//        }
		//    } else if ( targetFormat == "d" ) {
		//        if ( sourceFormat == "ms" ) {
		//            result = value / 86400000;
		//        } else if ( sourceFormat == "s" ) {
		//            result = value / 86400;
		//        } else if ( sourceFormat == "min" ) {
		//            result = value / 1440;
		//        } else if ( sourceFormat == "h" ) {
		//            result = value / 24;
		//        }
		//    }

		//    return result;
		//}

		#endregion

		#region Code Generation Helper
		public static string GenerateCSharpCode(this IEnumerable<BusinessObject> businessObjects)
		{
			StringBuilder sb = new StringBuilder();
			foreach ( BusinessObject bo in businessObjects ) {
				sb.AppendLine(bo.GenerateCSharpCode());
				sb.AppendLine();
			}
			return sb.ToString();
		}

		public static string GenerateCSharpCode(this BusinessObject businessObject)
		{
			return businessObject.Schema.GenerateCSharpCode();
		}

		public static string GenerateCSharpCode(this XmlSchema schema)
		{
			#region Old Code
			//if ( schema == null ) return string.Empty;
			//XmlSchemaSet xsdset = createXmlSchemaSetForDataContract();
			//xsdset.Add(schema);
			//// compile schema
			//try {
			//    xsdset.Compile();
			//} catch { return null; }

			//XsdDataContractImporter importer = new XsdDataContractImporter();
			//importer.Options = new ImportOptions();
			//importer.Options.Namespaces.Add("*", "OpenComposite.Data");
			//importer.Options.GenerateSerializable = true;
			////importer.Options.ImportXmlType = true;
			////importer.Options.DataContractSurrogate
			//importer.Import(xsdset);

			//CSharpCodeProvider codeProvider = new CSharpCodeProvider();
			//StringBuilder sb = new StringBuilder();
			//using ( StringWriter sw = new StringWriter(sb) ) {
			//    CodeGeneratorOptions options = new CodeGeneratorOptions();
			//    options.IndentString = "\t";
			//    codeProvider.GenerateCodeFromCompileUnit(importer.CodeCompileUnit, sw, options);
			//}
			//return sb.ToString();
			//XmlSchemas xsds = new XmlSchemas();
			//xsds.Add(schema);
			//xsds.Compile(null, true);
			////foreach ( XmlSchema xsd in xsdset.Schemas() ) {
			////    xsds.Add(xsd);
			////}
			//XmlSchemaImporter schemaImporter = new XmlSchemaImporter(xsds);

			//CodeCompileUnit ccu = new CodeCompileUnit();
			//CodeNamespace codeNs = new CodeNamespace("OpenComposite.Data");
			//ccu.Namespaces.Add(codeNs);
			//XmlCodeExporter codeExporter = new XmlCodeExporter(codeNs, ccu);
			//List<XmlTypeMapping> maps = new List<XmlTypeMapping>();

			//foreach ( XmlSchema xsd in xsds ) {
			//    foreach ( XmlSchemaType schemaType in xsd.SchemaTypes.Values ) {
			//        maps.Add(schemaImporter.ImportSchemaType(schemaType.QualifiedName));
			//    }
			//    foreach ( XmlSchemaElement schemaElement in xsd.Elements.Values ) {
			//        maps.Add(schemaImporter.ImportTypeMapping(schemaElement.QualifiedName));
			//    }
			//}
			//foreach ( XmlTypeMapping map in maps ) {
			//    codeExporter.ExportTypeMapping(map);
			//}
			#endregion

			// Collection of schemas for the XmlSchemaImporter
			XmlSchemas xsds = new XmlSchemas();
			xsds.Add(schema);
			xsds.Compile(null, true);
			XmlSchemaImporter imp = new XmlSchemaImporter(xsds);

			// System.CodeDom namespace for the XmlCodeExporter to put classes in
			CodeNamespace ns = new CodeNamespace("OpenComposite.Data");
			XmlCodeExporter exp = new XmlCodeExporter(ns);

			// Iterate schema items (top-level elements only) and generate code for each
			foreach ( XmlSchemaObject item in schema.Elements.Values ) {
				if ( item is XmlSchemaElement ) {
					// Import the mapping first
					XmlTypeMapping map = imp.ImportTypeMapping(
					  new XmlQualifiedName(( (XmlSchemaElement)item ).Name,
					  schema.TargetNamespace));
					// Export the code finally
					exp.ExportTypeMapping(map);
				}
			}


			CSharpCodeProvider codeProvider = new CSharpCodeProvider();
			StringBuilder sb = new StringBuilder();
			using ( StringWriter sw = new StringWriter(sb) ) {
				CodeGeneratorOptions options = new CodeGeneratorOptions() { IndentString = "\t" };
				codeProvider.GenerateCodeFromNamespace(ns, sw, options);
			}
			return sb.ToString();
		}

		private static XmlSchemaSet createXmlSchemaSetForDataContract()
		{
			XsdDataContractExporter ex = new XsdDataContractExporter();
			ex.Export(typeof(OpenComposite.EII.Designer.Workflow.Help));
			XmlSchemaSet xsdset = ex.Schemas;
			XmlSchema xsdRemove = null;
			foreach ( XmlSchema xsd in xsdset.Schemas() ) {
				if ( xsd.Elements.Contains(new XmlQualifiedName("Help", xsd.TargetNamespace)) ) {
					xsdRemove = xsd;
				}
			}
			xsdset.Remove(xsdRemove);
			return xsdset;
		}

		public static string GenerateCSharpCode(this ISupportLogicalPhysicalMapping lwm, bool isInput)
		{
			//if ( lwm.IsAssignedTo == LogicalMethodAssignedTo.HumanActivity ) return "";
			if ( lwm == null ) return "";

			StringBuilder sb = new StringBuilder();

			if ( lwm.WebService != null ) {
				#region Service Client
				MetadataSet mset = null;
				System.Web.Services.Description.ServiceDescription wsdl = null;
				//Collection<System.ServiceModel.Channels.Binding> bindings = null;
				string contractnspace = "Contract";
				using ( StringReader sr = new StringReader(lwm.WebService.MetaData) )
				using ( XmlReader xr = XmlReader.Create(sr) ) {
					mset = MetadataSet.ReadFrom(xr);
				}
				WsdlImporter wsdlimporter = new WsdlImporter(mset);
				if ( wsdlimporter.WsdlDocuments.Count > 0 ) {
					wsdl = wsdlimporter.WsdlDocuments[0];
					//bindings = wsdlimporter.ImportAllBindings();
				}
				CodeCompileUnit ccu = new CodeCompileUnit();
				ServiceContractGenerator generator = new ServiceContractGenerator(ccu);
				generator.Options = ServiceContractGenerationOptions.ClientClass |
									ServiceContractGenerationOptions.AsynchronousMethods |
									ServiceContractGenerationOptions.EventBasedAsynchronousMethods;
				generator.NamespaceMappings.Add(wsdl.TargetNamespace, contractnspace);
				generator.NamespaceMappings.Add("*", contractnspace);
				generator.NamespaceMappings.Add("", contractnspace);

				ContractDescription cdesc = wsdlimporter.ImportContract(wsdl.PortTypes[0]);
				generator.GenerateServiceContractType(cdesc);

				CSharpCodeProvider codeProvider = new CSharpCodeProvider();
				StringBuilder builder = new StringBuilder();
				using ( StringWriter sw = new StringWriter(builder) ) {
					CodeGeneratorOptions options = new CodeGeneratorOptions();
					options.IndentString = "\t";
					codeProvider.GenerateCodeFromCompileUnit(ccu, sw, options);
					// uncomment this for extended code access
					//provider.GenerateCodeFromCompileUnit(wl.XamlCodeCompileUnit, sw, options);
				}
				sb.AppendLine(builder.ToString());
				sb.AppendLine();
				#endregion
			}

			if ( isInput && lwm.InputBusinessObject != null ) {
				if ( lwm.InputBusinessObject.ExtendedProperties.BusinessObjectCode != null ) {
					sb.AppendLine(lwm.InputBusinessObject.ExtendedProperties.BusinessObjectCode);
				} else {
					lwm.InputBusinessObject.ExtendedProperties.BusinessObjectCode = lwm.InputBusinessObject.GenerateCSharpCode();
					lwm.InputBusinessObject.Save();
					sb.AppendLine(lwm.InputBusinessObject.ExtendedProperties.BusinessObjectCode);
				}
				sb.AppendLine();
				//sb.AppendLine(lwm.GetAssignedWebMethod().InputSchema.GenerateCSharpCode());
			} else if ( lwm.OutputBusinessObject != null ) {
				if ( lwm.OutputBusinessObject.ExtendedProperties.BusinessObjectCode != null ) {
					sb.AppendLine(lwm.OutputBusinessObject.ExtendedProperties.BusinessObjectCode);
				} else {
					lwm.OutputBusinessObject.ExtendedProperties.BusinessObjectCode = lwm.OutputBusinessObject.GenerateCSharpCode();
					lwm.OutputBusinessObject.Save();
					sb.AppendLine(lwm.OutputBusinessObject.ExtendedProperties.BusinessObjectCode);
				}
				sb.AppendLine();
				//sb.AppendLine(lwm.GetAssignedWebMethod().OutputSchema.GenerateCSharpCode());
			}
			return sb.ToString();
		}

		public static string GenerateHeaderText(this LogicalActivity la)
		{
			string text = new BusinessObject[] { la.InputBusinessObject, la.OutputBusinessObject }.GenerateCSharpCode();
			text += @"namespace OpenComposite.Data {
	public class Mapping {
		public " + la.InputBusinessObject.Name + @" Input {get;set;}
		public " + la.OutputBusinessObject.Name + @" Output {get;set;}
		
		private void doMapping() {";
			return text;
		}

		public static string GenerateHeaderText(this ISupportLogicalPhysicalMapping lwm, bool isInput, params string[] additionalNamespaces)
		{
			if ( lwm == null ) return "";
			string text = lwm.GenerateCSharpCode(isInput);
			string[] types = null;
			string[] names = null;
			if ( lwm.WebMethod != null ) {
				types = lwm.WebMethod.InputTypeName.Split(';');
				names = lwm.WebMethod.InputVariableName.Split(';');
			} else if ( lwm.CallbackWebMethod != null ) {
				types = lwm.CallbackWebMethod.InputTypeName.Split(';');
				names = lwm.CallbackWebMethod.InputVariableName.Split(';');
			} else if ( lwm.SendMessageQueue != null || lwm.ReceiveMessageQueue != null ) {
				types = new string[] { "object" };
				names = new string[] { "obj" };
			}

			//switch ( lwm.IsAssignedTo ) {
			//    case LogicalMethodAssignedTo.WebServiceMethod:
			//        lwm.WebMethod.InputTypeName.Split(';');
			//        lwm.WebMethod.InputVariableName.Split(';');
			//        break;
			//    case LogicalMethodAssignedTo.HumanActivity:
			//        types = new string[] { lwm.HumanActivity.FormSchemaName };
			//        names = new string[] { "FormSchema" };
			//        break;
			//    case LogicalMethodAssignedTo.EndpointRule:
			//        break;
			//    default:
			//        break;
			//}

			//if ( types == null || names == null ) return "";
			string usings = "using System;".AppendLine("using System.Data;").
				AppendLine("using System.IO;").AppendLine("using System.Collections;").
				AppendLine("using System.Collections.Generic;").AppendLine("using System.Xml;").
				AppendLine("using OpenComposite.Base;");

			text += string.Format("namespace OpenComposite.Data {1}{0}{3}public class Mapping {1}{0}private {2} {4}{5}(",
				Environment.NewLine, "{",
				isInput ? "bool" : ( lwm.InputBusinessObject == null ? "void" : lwm.InputBusinessObject.Name ), usings,
				lwm.Name, isInput ? "InputMapping" : "OutputMapping");

			if ( isInput ) {
				if ( lwm.InputBusinessObject != null ) {
					text += string.Format("{0} input0", lwm.InputBusinessObject.Name);
				}
				if ( types != null ) {
					text += ", ";
					for ( int i = 0; i < types.Length; i++ ) {
						text += string.Format("out {0} {1}", types[i],
									names.Length < i ? string.Format("output{0}", i) : names[i]);
						if ( i < types.Length - 1 ) text += ", ";
					}
				}
			} else {
				string typeName = null;
				if ( lwm.WebMethod != null ) {
					typeName = lwm.WebMethod.OutputTypeName.Split(';')[0];
				} else if ( lwm.CallbackWebMethod != null ) {
					typeName = lwm.CallbackWebMethod.OutputTypeName.Split(';')[0];
				} else if ( lwm.SendMessageQueue != null || lwm.ReceiveMessageQueue != null ) {
					typeName = "object";
				}
				text += string.Format("{0} {1}", typeName, "input");
			}

			text += string.Format(") {1}{0}", Environment.NewLine, "{");

			text += isInput ? string.Format("{0}bool isOk = true;", Environment.NewLine) :
						string.Format("{0}{1} result = null;{0}", Environment.NewLine,
					isInput ? lwm.InputBusinessObject.Name : lwm.OutputBusinessObject.Name);

			return text;
		}

		public static string AddLeadingTabs(this string text, int tabCount)
		{
			if ( text == null || tabCount < 1 ) return text;
			string tabs = new string('\t', tabCount);
			text = text.Insert(0, tabs).Replace("\n", string.Format("\n{0}", tabs));
			return text;
		}
		public static string AppendLine(this string baseText)
		{
			return string.Format("{0}{1}", baseText, Environment.NewLine);
		}
		public static string AppendLine(this string baseText, string value)
		{
			return string.Format("{0}{1}{2}", baseText, Environment.NewLine, value);
		}

		public static void AddDistinctByName(this CodeTypeMemberCollection members, CodeTypeMember member)
		{
			if ( members == null || member == null ) return;
			string methName = member.Name;
			int i = ( from CodeTypeMember m in members
					  where m != null && m.Name == methName
					  select m ).Count();
			if ( i < 1 ) {
				members.Add(member);
			} else { }
		}
		#endregion

		#region Service Helpers
		public static T GetService<T>(this IServiceProvider serviceProvider)
		{
			return (T)serviceProvider.GetService(typeof(T));
		}
		#endregion

		#region Icon Helpers

		public static Icon GetFileIcon(string fileName)
		{
			return IconReader.GetFileIcon(fileName, IconReader.IconSize.Small, false);
		}
		/// <summary>
		/// Provides static methods to read system icons for both folders and files.
		/// </summary>
		/// <example>
		/// <code>IconReader.GetFileIcon("c:\\general.xls");</code>
		/// </example>
		private class IconReader
		{
			/// <summary>
			/// Options to specify the size of icons to return.
			/// </summary>
			public enum IconSize
			{
				/// <summary>
				/// Specify large icon - 32 pixels by 32 pixels.
				/// </summary>
				Large = 0,
				/// <summary>
				/// Specify small icon - 16 pixels by 16 pixels.
				/// </summary>
				Small = 1
			}

			/// <summary>
			/// Options to specify whether folders should be in the open or closed state.
			/// </summary>
			public enum FolderType
			{
				/// <summary>
				/// Specify open folder.
				/// </summary>
				Open = 0,
				/// <summary>
				/// Specify closed folder.
				/// </summary>
				Closed = 1
			}

			/// <summary>
			/// Returns an icon for a given file - indicated by the name parameter.
			/// </summary>
			/// <param name="name">Pathname for file.</param>
			/// <param name="size">Large or small</param>
			/// <param name="linkOverlay">Whether to include the link icon</param>
			/// <returns>System.Drawing.Icon</returns>
			public static Icon GetFileIcon(string name, IconSize size, bool linkOverlay)
			{
				Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
				uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES;

				if ( true == linkOverlay ) flags += Shell32.SHGFI_LINKOVERLAY;

				/* Check the size specified for return. */
				if ( IconSize.Small == size ) {
					flags += Shell32.SHGFI_SMALLICON;
				} else {
					flags += Shell32.SHGFI_LARGEICON;
				}

				Shell32.SHGetFileInfo(name,
					Shell32.FILE_ATTRIBUTE_NORMAL,
					ref shfi,
					(uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi),
					flags);

				// Copy (clone) the returned icon to a new object, thus allowing us to clean-up properly
				System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone();
				User32.DestroyIcon(shfi.hIcon);		// Cleanup
				return icon;
			}

			/// <summary>
			/// Used to access system folder icons.
			/// </summary>
			/// <param name="size">Specify large or small icons.</param>
			/// <param name="folderType">Specify open or closed FolderType.</param>
			/// <returns>System.Drawing.Icon</returns>
			public static Icon GetFolderIcon(IconSize size, FolderType folderType)
			{
				// Need to add size check, although errors generated at present!
				uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES;

				if ( FolderType.Open == folderType ) {
					flags += Shell32.SHGFI_OPENICON;
				}

				if ( IconSize.Small == size ) {
					flags += Shell32.SHGFI_SMALLICON;
				} else {
					flags += Shell32.SHGFI_LARGEICON;
				}

				// Get the folder icon
				Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
				Shell32.SHGetFileInfo(null,
					Shell32.FILE_ATTRIBUTE_DIRECTORY,
					ref shfi,
					(uint)System.Runtime.InteropServices.Marshal.SizeOf(shfi),
					flags);

				System.Drawing.Icon.FromHandle(shfi.hIcon);	// Load the icon from an HICON handle

				// Now clone the icon, so that it can be successfully stored in an ImageList
				System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone();

				User32.DestroyIcon(shfi.hIcon);		// Cleanup
				return icon;
			}
		}



		#endregion

		#region String Helpers
		/// <summary>
		/// Determines whether the specified string is null or has zero length.
		/// </summary>
		/// <param name="value">The value to check.</param>
		/// <returns>
		/// 	<c>true</c> if specified string is null or has zero length; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsNullOrEmpty(this string value)
		{
			return value == null || value.Length == 0;
		}
		/// <summary>
		/// Returns altValue if value is null or empty; otherwise false.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <param name="altValue">The alternative value that is returned if value is null.</param>
		/// <returns></returns>
		public static string IfNullOrEmpty(this string value, string altValue)
		{
			return value.IsNullOrEmpty() ? altValue : value;
		}
		#endregion

		#region Graphics (Paint) Helpers
		public static void DrawImageAndString(this Graphics graphics, Image image, string text, RectangleF rectangle)
		{
			DrawImageAndString(graphics, image, text, rectangle, true);
		}
		public static void DrawImageAndString(this Graphics graphics, Image image, string text, RectangleF rectangle, bool imageBeforeText)
		{
		}
		#endregion

		#region DLL to DB Helpers
		public static byte[] ToByteArray(this Assembly assembly)
		{
			if ( assembly == null || assembly.Location.IsNullOrEmpty() ) return null;
			return FileToByteArray(assembly.Location);
		}
		public static byte[] FileToByteArray(string fileName)
		{
			byte[] value;
			try {
				using ( Stream s = new FileStream(fileName, FileMode.Open, FileAccess.Read) ) {
					s.Position = 0;
					value = new byte[s.Length];
					s.Read(value, 0, (int)s.Length);
				}
			} catch { return null; }
			return value;
		}
		#endregion

		#region Dump Object (Debug/Trace Helper)
		internal static void DumpObject(this object obj, bool background)
		{
#if DEBUG
			ObjectDumper.Dump(obj, background, DumpType.DelayedOutput);
#else
			Console.WriteLine("Dump omitted in release build.");
#endif
		}
		internal static string DumpObject(this object obj, bool background, DumpType dumpType)
		{
#if DEBUG
			return ObjectDumper.Dump(obj, background, dumpType);
#else
			return "Dump omitted in release build.";
#endif
		}
		#region private class ObjectDumper
		internal enum DumpType
		{
			InstantOutput = 0,
			DelayedOutput,
			AsString,
		}
		private class ObjectDumper
		{
			private static StringBuilder _builder = null;
			private static DumpType _dumpType = DumpType.DelayedOutput;
			private static int _maxDepth = 4;
			public static string Dump(object o, bool startInBackground, DumpType dumpType)
			{
				_builder = new StringBuilder();
				_dumpType = dumpType;
				if ( startInBackground ) {
					ParameterizedThreadStart pts = new ParameterizedThreadStart(BeginDump);
					Thread t = new Thread(pts);
					t.IsBackground = true;
					t.Start(o);
					return null;
				} else {
					Dump(o, 0, new ArrayList());
					if ( _dumpType == DumpType.AsString ) {
						return _builder.ToString();
					} else {
						Debug.WriteLine(_builder.ToString());
						return null;
					}
				}
			}

			/// <summary>
			/// Begins the dump for async var dump.
			/// </summary>
			/// <param name="o">The object to dump.</param>
			private static void BeginDump(object o)
			{
				Dump(o, 0, new ArrayList());
			}

			private static string Pad(int level, string msg, params object[] args)
			{
				string val = String.Format(msg, args);
				return val.PadLeft(( level * 4 ) + val.Length);
			}

			private static void Dump(object o, int level, ArrayList previous)
			{
				Type type = null;

				if ( o != null ) {
					type = o.GetType();
				}

				Dump(o, type, null, level, previous);
			}

			private static void Dump(object o, Type type, string name, int level, ArrayList previous)
			{
				if ( level >= _maxDepth ) return;
				if ( o == null ) {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level, "{0} ({1}): (null)", name, type == null ? "(null)" : type.Name));
					else
						_builder.AppendLine(Pad(level, "{0} ({1}): (null)", name, type == null ? "(null)" : type.Name));
					return;
				}

				if ( previous.Contains(o) ) {
					return;
				}

				previous.Add(o);

				if ( type.IsPrimitive || o is string ) {
					DumpPrimitive(o, type, name, level, previous);
				} else {
					DumpComposite(o, type, name, level, previous);
				}
			}

			private static void DumpPrimitive(object o, Type type, string name, int level, ArrayList previous)
			{
				if ( name != null ) {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level, "{0} ({1}): {2}", name, type.Name, o));
					else
						_builder.AppendLine(Pad(level, "{0} ({1}): {2}", name, type.Name, o));
				} else {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level, "({0}) {1}", type.Name, o));
					else
						_builder.AppendLine(Pad(level, "({0}) {1}", type.Name, o));
				}
			}

			private static void DumpComposite(object o, Type type, string name, int level, ArrayList previous)
			{

				if ( name != null ) {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level, "{0} ({1}):", name, type.Name));
					else
						_builder.AppendLine(Pad(level, "{0} ({1}):", name, type.Name));
				} else {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level, "({0})", type.Name));
					else
						_builder.AppendLine(Pad(level, "({0})", type.Name));
				}

				if ( o is IDictionary ) {
					DumpDictionary((IDictionary)o, level, previous);
				} else if ( o is ICollection ) {
					DumpCollection((ICollection)o, level, previous);
				} else {
					MemberInfo[] members = o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public |
																	BindingFlags.NonPublic);

					foreach ( MemberInfo member in members ) {
						try {
							DumpMember(o, member, level, previous);
						} catch { }
					}
				}
			}

			private static void DumpCollection(ICollection collection, int level, ArrayList previous)
			{
				foreach ( object child in collection ) {
					Dump(child, level + 1, previous);
				}
			}

			private static void DumpDictionary(IDictionary dictionary, int level, ArrayList previous)
			{
				foreach ( object key in new List<object>(dictionary.Keys.Cast<object>()) ) {
					if ( _dumpType == DumpType.InstantOutput )
						Debug.WriteLine(Pad(level + 1, "[{0}] ({1}):", key, key.GetType().Name));
					else
						_builder.AppendLine(Pad(level + 1, "[{0}] ({1}):", key, key.GetType().Name));

					Dump(dictionary[key], level + 2, previous);
				}
			}

			private static void DumpMember(object o, MemberInfo member, int level, ArrayList previous)
			{
				if ( member is MethodInfo || member is ConstructorInfo ||
					member is EventInfo )
					return;

				if ( member is FieldInfo ) {
					FieldInfo field = (FieldInfo)member;

					string name = member.Name;
					if ( ( field.Attributes & FieldAttributes.Public ) == 0 ) {
						name = "#" + name;
					}

					Dump(field.GetValue(o), field.FieldType, name, level + 1, previous);
				} else if ( member is PropertyInfo ) {
					PropertyInfo prop = (PropertyInfo)member;

					if ( prop.GetIndexParameters().Length == 0 && prop.CanRead ) {
						string name = member.Name;
						MethodInfo getter = prop.GetGetMethod();

						if ( getter != null && ( getter.Attributes & MethodAttributes.Public ) == 0 ) {
							name = "#" + name;
						}

						Dump(prop.GetPropertyValue(o), prop.PropertyType, name, level + 1, previous);
					}
				}
			}
		}
		[DebuggerStepThrough]
		private static object GetPropertyValue(this PropertyInfo prop, object obj)
		{
			try {
				return prop.GetValue(obj, null);
			} catch { return null; }
		}
		#endregion
		#endregion

		#region Business Object Helpers
		public static void ReadSchemaNew(XmlSchema xsd, BusinessObject bobject)
		{
			XmlSchemas schemas = new XmlSchemas();
			schemas.Add(xsd);
			schemas.Compile(new ValidationEventHandler(set_ValidationEventHandler), true);

			CodeGenerationOptions options = CodeGenerationOptions.GenerateProperties;
			CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
			ImportContext context = new ImportContext(new CodeIdentifiers(true), true);
			CodeNamespace codens = new CodeNamespace("");
			CodeCompileUnit codecu = new CodeCompileUnit();

			XmlCodeExporter codeexporter = new XmlCodeExporter(codens, codecu, CodeGenerationOptions.GenerateProperties);
			XmlSchemaImporter xsdimporter = new XmlSchemaImporter(schemas, options, provider, context);

			codens.Imports.Add(new CodeNamespaceImport(typeof(XmlAttributeAttribute).Namespace));

			List<XmlTypeMapping> list = new List<XmlTypeMapping>();
			foreach ( XmlSchema schema in schemas ) {
				foreach ( XmlSchemaElement item in schema.Elements.Values ) {
					if ( !item.IsAbstract ) {
						list.Add(xsdimporter.ImportTypeMapping(item.QualifiedName));
					}
				}
			}
			foreach ( var mapping in list ) {
				codeexporter.ExportTypeMapping(mapping);
			}
		}
		public static void ReadSchema(XmlSchema xsd, BusinessObject bobject)
		{
			XmlSchemaSet set = new XmlSchemaSet();
			set.Add(xsd);
			set.ValidationEventHandler += new ValidationEventHandler(set_ValidationEventHandler);
			set.Compile();

			foreach ( object item in xsd.Elements.Values ) {
				XmlSchemaElement e = item as XmlSchemaElement;
				if ( e != null ) {
					bobject.BeginEdit();
					bobject.Name = e.Name;
					bobject.ExtendedProperties.Namespace = e.QualifiedName.Namespace;
					if ( e.SchemaTypeName != null ) {
						bobject.ExtendedProperties.TypeName = e.SchemaTypeName.Name;
						bobject.ExtendedProperties.TypeNamespace = e.SchemaTypeName.Namespace;
					}
					bobject.DomainId = Global.Status.CurrentDomainId;
					bobject.EndEdit(false);
					bobject.Save(false);
					XmlSchemaComplexType ct = e.ElementSchemaType as XmlSchemaComplexType;
					if ( ct != null ) {
						readSchema(ct, bobject);
					}
				}
			}
		}
		private static void readSchema(XmlSchemaComplexType complexType, BusinessObject targetbobject)
		{
			XmlSchemaGroupBase grpBase = complexType.Particle as XmlSchemaGroupBase;
			XmlSchemaGroupRef grpRef = complexType.Particle as XmlSchemaGroupRef;
			if ( complexType.Particle is XmlSchemaSequence ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.Sequence;
			} else if ( complexType.Particle is XmlSchemaGroupRef ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.Group;
			} else if ( complexType.Particle is XmlSchemaChoice ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.Choice;
			} else if ( complexType.Particle is XmlSchemaAll ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.All;
			} else if ( complexType.Particle is XmlSchemaElement ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.Element;
			} else if ( complexType.Particle is XmlSchemaAny ) {
				targetbobject.ExtendedProperties.Particle = ParticleType.Any;
			}
			if ( grpBase != null ) {
				targetbobject.BusinessObjectFields.Clear();
				foreach ( XmlSchemaObject xobj in grpBase.Items ) {
					XmlSchemaAttribute xsa = xobj as XmlSchemaAttribute;
					XmlSchemaElement xse = xobj as XmlSchemaElement;
					if ( xsa != null ) {
						#region add a field for an XmlSchemaAttribute
						Noun noun = Global.Data.FindItemByName<Noun>(xsa.Name);
						if ( noun == null ) {
							noun = Global.Repository.GetNewItem<Noun>();
							noun.BeginEdit();
							noun.Name = xsa.Name;
							noun.DataType = xsa.SchemaTypeName.Name;
							noun.DomainId = targetbobject.DomainId;
							noun.EndEdit(true);
							Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, noun);
						}
						BusinessObjectField field = targetbobject.CreateNewField();
						field.Noun = noun;
						field.Name = xsa.Name;
						field.IsXmlAttribute = true;
						field.Properties.AttributeUse = xsa.Use;
						field.Properties.AttributeDefaultValue = xsa.DefaultValue;
						field.Properties.AttributeFixedValue = xsa.FixedValue;
						targetbobject.BusinessObjectFields.Add(field);
						#endregion
					} else if ( xse != null ) {
						if ( xse.ElementSchemaType is XmlSchemaSimpleType ) {
							#region add a field for an XmlSchemaSimpleType element
							Noun noun = Global.Data.FindItemByName<Noun>(xse.Name);
							if ( noun == null ) {
								noun = Global.Repository.GetNewItem<Noun>();
								noun.BeginEdit();
								noun.Name = xse.Name;
								if ( xse.SchemaTypeName != null && !xse.SchemaTypeName.IsEmpty ) {
									noun.DataType = xse.SchemaTypeName.Name;
								} else if ( xse.SchemaType is XmlSchemaSimpleType ) {
									XmlSchemaSimpleType st = (XmlSchemaSimpleType)xse.SchemaType;
									if ( st.DerivedBy == XmlSchemaDerivationMethod.Restriction ) {
										#region read restrictions
										XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
										noun.DataType = rest.BaseTypeName.Name;
										noun.Properties.Enumeration.Clear();
										foreach ( XmlSchemaObject xso in rest.Facets ) {
											XmlSchemaFacet facet = xso as XmlSchemaFacet;
											if ( xso is XmlSchemaLengthFacet ) {
												noun.Properties.Length = getUInt(facet.Value);
											} else if ( xso is XmlSchemaMinLengthFacet ) {
												noun.Properties.MinLength = getUInt(facet.Value);
											} else if ( xso is XmlSchemaMaxLengthFacet ) {
												noun.Properties.MaxLength = getUInt(facet.Value);
											} else if ( xso is XmlSchemaTotalDigitsFacet ) {
												noun.Properties.TotalDigits = getUInt(facet.Value);
											} else if ( xso is XmlSchemaFractionDigitsFacet ) {
												noun.Properties.FractionDigits = getUInt(facet.Value);
											} else if ( xso is XmlSchemaEnumerationFacet ) {
												noun.Properties.Enumeration.Add(facet.Value);
											} else if ( xso is XmlSchemaMinExclusiveFacet ) {
												noun.Properties.MinExclusive = getUInt(facet.Value);
											} else if ( xso is XmlSchemaMinInclusiveFacet ) {
												noun.Properties.MinInclusive = getUInt(facet.Value);
											} else if ( xso is XmlSchemaMaxExclusiveFacet ) {
												noun.Properties.MaxExclusive = getUInt(facet.Value);
											} else if ( xso is XmlSchemaMaxInclusiveFacet ) {
												noun.Properties.MaxInclusive = getUInt(facet.Value);
											} else if ( xso is XmlSchemaWhiteSpaceFacet ) {
												noun.Properties.WhiteSpace = getWhiteSpaceHandling(facet.Value);
											} else if ( xso is XmlSchemaPatternFacet ) {
												noun.Properties.Pattern = facet.Value;
											}
										}
										#endregion
									}
								}
								noun.DomainId = targetbobject.DomainId;
								noun.EndEdit(true);
								Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, noun);
							}
							BusinessObjectField field = targetbobject.CreateNewField();
							field.Noun = noun;
							field.Name = xse.Name;
							field.MaxOccurs = ( xse.MaxOccursString == BusinessObjectField.Unbounded ? -1 : (int)xse.MaxOccurs );
							field.MinOccurs = ( xse.MinOccursString == BusinessObjectField.Unbounded ? -1 : (int)xse.MinOccurs );
							field.IsXmlAttribute = false;
							targetbobject.BusinessObjectFields.Add(field);
							#endregion
						} else {
							#region generate sub business objects for XmlSchemaComplexTypes
							string nm;
							if ( xse.SchemaTypeName != null && !xse.SchemaTypeName.IsEmpty ) {
								nm = xse.SchemaTypeName.Name;
							} else {
								nm = xse.Name;
							}
							BusinessObject boNew = Global.Data.FindItemByName<BusinessObject>(nm);
							if ( boNew == null ) {
								boNew = Global.Repository.GetNewItem<BusinessObject>();
								boNew.BeginEdit();
								if ( xse.SchemaTypeName != null ) {
									boNew.Name = xse.SchemaTypeName.Name;
									boNew.ExtendedProperties.Namespace = xse.SchemaTypeName.Namespace;
									boNew.ExtendedProperties.TypeName = xse.SchemaTypeName.Name;
									boNew.ExtendedProperties.TypeNamespace = xse.SchemaTypeName.Namespace;
								} else {
									boNew.Name = xse.Name;
									boNew.ExtendedProperties.Namespace = xse.QualifiedName.Namespace;
								}
								boNew.DomainId = targetbobject.DomainId;
								boNew.EndEdit(false);
								boNew.Save(false);
								Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, boNew);
								XmlSchemaComplexType ct = xse.ElementSchemaType as XmlSchemaComplexType;
								if ( ct != null ) {
									readSchema(ct, boNew);
								}
							}
							BusinessObjectField field = targetbobject.CreateNewField();
							field.BusinessObject = boNew;
							field.Name = xse.Name;
							field.MaxOccurs = ( xse.MaxOccursString == BusinessObjectField.Unbounded ? -1 : (int)xse.MaxOccurs );
							field.MinOccurs = ( xse.MinOccursString == BusinessObjectField.Unbounded ? -1 : (int)xse.MinOccurs );
							field.IsXmlAttribute = false;
							targetbobject.BusinessObjectFields.Add(field);
							#endregion
						}
					}
				}
			} else if ( grpRef != null ) {
				// TODO: handle group reference
			}
			targetbobject.Save(false);
		}
		private static uint? getUInt(string str)
		{
			uint val;
			if ( !uint.TryParse(str, out val) ) return null;
			return val;
		}
		private static Noun.WhiteSpaceHandling? getWhiteSpaceHandling(string s)
		{
			Noun.WhiteSpaceHandling? result;
			try {
				result = (Noun.WhiteSpaceHandling)Enum.Parse(typeof(Noun.WhiteSpaceHandling), s, true);
			} catch {
				result = null;
			}
			return result;
		}

		private static void set_ValidationEventHandler(object sender, ValidationEventArgs e)
		{
			MessageBox.Show(e.Message, "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}

		#endregion
	}
}
